package com.cccyy.encry.sm4;

import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;

import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

public class Smell {
    public static byte[] encrypt(byte[] data, byte[] key, byte[] iv) throws Exception {
        SM4Engine sm4Engine = new SM4Engine();
        CBCBlockCipher cbcBlockCipher = new CBCBlockCipher(sm4Engine);
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(cbcBlockCipher);

        KeyParameter keyParameter = new KeyParameter(key);
        ParametersWithIV parametersWithIV = new ParametersWithIV(keyParameter, iv);

        cipher.init(true, parametersWithIV);
        byte[] output = new byte[cipher.getOutputSize(data.length)];
        int length = cipher.processBytes(data, 0, data.length, output, 0);
        cipher.doFinal(output, length);

        return output;
    }

    public static byte[] decrypt(byte[] data, byte[] key, byte[] iv) throws Exception {
        SM4Engine sm4Engine = new SM4Engine();
        CBCBlockCipher cbcBlockCipher = new CBCBlockCipher(sm4Engine);
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(cbcBlockCipher);

        KeyParameter keyParameter = new KeyParameter(key);
        ParametersWithIV parametersWithIV = new ParametersWithIV(keyParameter, iv);

        cipher.init(false, parametersWithIV);
        byte[] output = new byte[cipher.getOutputSize(data.length)];
        int length = cipher.processBytes(data, 0, data.length, output, 0);
        cipher.doFinal(output, length);

        return output;
    }

    public static void main(String[] args) throws Exception {
        String plaintext = "Hello, SM4!";
        byte[] data = plaintext.getBytes(StandardCharsets.UTF_8);
        byte[] key = new byte[16]; // 128-bit key
        byte[] iv = new byte[16]; // 128-bit IV

        // Generate key and IV for demonstration purposes
        new SecureRandom().nextBytes(key);
        new SecureRandom().nextBytes(iv);

        byte[] encrypted = encrypt(data, key, iv);
        byte[] decrypted = decrypt(encrypted, key, iv);

        System.out.println("Plaintext: " + plaintext);
        System.out.println("Encrypted: " + new String(encrypted, StandardCharsets.UTF_8));
        System.out.println("Decrypted: " + new String(decrypted, StandardCharsets.UTF_8));
    }
}
